/*
 * Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
 *
 * Licensed under the Mulan PSL v2.
 * You can use this file according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of the License at
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
 * FOR MORE DETAILS.
 */

#pragma once

#include <chrono>
#include <memory>

#include "DBManager/Database/CachePool.h"
#include "DBManager/Database/HDF5Database.h"

SG_DBMANAGER_NAMESPACE_OPEN

/**
 * @class CacheHelper
 * @brief 缓存池辅助工具类，提供便捷的缓存操作方法
 */
class DBManager_DECLSPEC CacheHelper
{
  public:
    /**
     * @brief 构造函数
     * @param database HDF5Database实例
     */
    explicit CacheHelper (HDF5Database& database) : m_database (database)
    {}

    /**
     * @brief 缓存vector数据
     * @tparam T vector元素类型
     * @param key 缓存键
     * @param data vector指针
     * @param ttlSeconds TTL时间（秒，0表示永不过期）
     * @return 缓存成功返回true
     */
    template <typename T>
    bool CacheVector (const std::string& key, std::vector<T>* data, int ttlSeconds = 60000)
    {
        auto ttl = ttlSeconds > 0 ? std::chrono::milliseconds (ttlSeconds * 1000) : std::chrono::milliseconds (0);
        return m_database.GetCachePool ().Put (key, data, ttl);
    }

    /**
     * @brief 缓存unordered_map数据
     * @tparam K map的键类型
     * @tparam V map的值类型
     * @param key 缓存键
     * @param data unordered_map指针
     * @param ttlSeconds TTL时间（秒，0表示永不过期）
     * @return 缓存成功返回true
     */
    template <typename K, typename V>
    bool CacheUnorderedMap (const std::string& key, std::unordered_map<K, V>* data, int ttlSeconds = 60000)
    {
        auto ttl = ttlSeconds > 0 ? std::chrono::milliseconds (ttlSeconds * 1000) : std::chrono::milliseconds (0);
        return m_database.GetCachePool ().Put (key, data, ttl);
    }

    /**
     * @brief 缓存set数据
     * @tparam T set元素类型
     * @param key 缓存键
     * @param data set指针
     * @param ttlSeconds TTL时间（秒，0表示永不过期）
     * @return 缓存成功返回true
     */
    template <typename T>
    bool CacheSet (const std::string& key, std::set<T>* data, int ttlSeconds = 60000)
    {
        auto ttl = ttlSeconds > 0 ? std::chrono::milliseconds (ttlSeconds * 1000) : std::chrono::milliseconds (0);
        return m_database.GetCachePool ().Put (key, data, ttl);
    }

    /**
     * @brief 获取缓存的vector数据
     * @tparam T vector元素类型
     * @param key 缓存键
     * @return vector指针，不存在返回nullptr
     */
    template <typename T>
    std::vector<T>* GetVector (const std::string& key)
    {
        return m_database.GetCachePool ().Get<std::vector<T>> (key);
    }

    /**
     * @brief 获取缓存的vector数据（快速版本，跳过过期检查）
     * @tparam T vector元素类型
     * @param key 缓存键
     * @return vector指针，不存在返回nullptr
     * @note 此版本假设缓存项不会过期，跳过过期检查以提高性能
     */
    template <typename T>
    std::vector<T>* GetVectorFast (const std::string& key)
    {
        return m_database.GetCachePool ().GetFast<std::vector<T>> (key);
    }

    /**
     * @brief 获取缓存的unordered_map数据
     * @tparam K map的键类型
     * @tparam V map的值类型
     * @param key 缓存键
     * @return unordered_map指针，不存在返回nullptr
     */
    template <typename K, typename V>
    std::unordered_map<K, V>* GetUnorderedMap (const std::string& key)
    {
        return m_database.GetCachePool ().Get<std::unordered_map<K, V>> (key);
    }

    /**
     * @brief 获取缓存的unordered_map数据（快速版本，跳过过期检查）
     * @tparam K map的键类型
     * @tparam V map的值类型
     * @param key 缓存键
     * @return unordered_map指针，不存在返回nullptr
     * @note 此版本假设缓存项不会过期，跳过过期检查以提高性能
     */
    template <typename K, typename V>
    std::unordered_map<K, V>* GetUnorderedMapFast (const std::string& key)
    {
        return m_database.GetCachePool ().GetFast<std::unordered_map<K, V>> (key);
    }

    /**
     * @brief 获取缓存的set数据
     * @tparam T set元素类型
     * @param key 缓存键
     * @return set指针，不存在返回nullptr
     */
    template <typename T>
    std::set<T>* GetSet (const std::string& key)
    {
        return m_database.GetCachePool ().Get<std::set<T>> (key);
    }

    /**
     * @brief 获取缓存的set数据（快速版本，跳过过期检查）
     * @tparam T set元素类型
     * @param key 缓存键
     * @return set指针，不存在返回nullptr
     * @note 此版本假设缓存项不会过期，跳过过期检查以提高性能
     */
    template <typename T>
    std::set<T>* GetSetFast (const std::string& key)
    {
        return m_database.GetCachePool ().GetFast<std::set<T>> (key);
    }

    /**
     * @brief 查找或创建vector缓存项
     * @tparam T vector元素类型
     * @param key 缓存键
     * @param initialCapacity 初始容量
     * @return vector指针
     */
    template <typename T>
    std::vector<T>* LookupOrCreateVector (const std::string& key, size_t initialCapacity = 0)
    {
        auto* vec = m_database.GetCachePool ().Get<std::vector<T>> (key);
        if (!vec)
        {
            vec = new std::vector<T>;
            m_database.GetCachePool ().Put (key, vec);
        }
        vec->reserve (initialCapacity);
        return vec;
    }

    /**
     * @brief 查找或创建vector缓存项（快速版本，适用于永不过期的缓存项）
     * @tparam T vector元素类型
     * @param key 缓存键
     * @param initialCapacity 初始容量
     * @return vector指针
     * @note 此版本跳过过期检查，适用于确定不会过期的缓存项
     */
    template <typename T>
    std::vector<T>* LookupOrCreateVectorFast (const std::string& key, size_t initialCapacity = 0)
    {
        auto* vec = m_database.GetCachePool ().GetFast<std::vector<T>> (key);
        if (!vec)
        {
            vec = new std::vector<T>;
            // 对于新创建的项目，使用永不过期的TTL
            m_database.GetCachePool ().Put (key, vec, std::chrono::milliseconds (0));
        }
        vec->reserve (initialCapacity);
        return vec;
    }

    /**
     * @brief 检查缓存项是否存在
     * @param key 缓存键
     * @return 存在且未过期返回true
     */
    bool Contains (const std::string& key)
    {
        return m_database.GetCachePool ().Contains (key);
    }

    /**
     * @brief 通用的获取缓存项方法
     * @tparam T 数据类型
     * @param key 缓存键
     * @return 数据指针，不存在或过期返回nullptr
     */
    template <typename T>
    T* Get (const std::string& key)
    {
        return m_database.GetCachePool ().Get<T> (key);
    }

    /**
     * @brief 通用的获取缓存项方法（快速版本）
     * @tparam T 数据类型
     * @param key 缓存键
     * @return 数据指针，不存在返回nullptr
     * @note 跳过过期检查以提高性能
     */
    template <typename T>
    T* GetFast (const std::string& key)
    {
        return m_database.GetCachePool ().GetFast<T> (key);
    }

    /**
     * @brief 获取缓存统计信息
     * @return 统计信息字符串
     */
    bool Remove (const std::string& key)
    {
        return m_database.GetCachePool ().Remove (key);
    }

    /**
     * @brief 获取缓存统计信息
     * @return 统计信息字符串
     */
    std::string GetCacheStatistics () const
    {
        return m_database.GetCachePool ().GetStatistics ();
    }

    /**
     * @brief 手动清理过期缓存项
     * @return 清理的项目数量
     */
    std::size_t CleanupExpiredItems ()
    {
        return m_database.GetCachePool ().CleanupExpired ();
    }

  private:
    HDF5Database& m_database;  ///< 数据库引用
};

SG_DBMANAGER_NAMESPACE_CLOSE
